package com.mdb.open.trade.facade.trade;

import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.collect.Maps;
import com.mdb.bc.api.data.ResultEx;
import com.mdb.bc.autoconfigure.database.MdbDataSource;
import com.mdb.bc.utils.ObjectUtil;
import com.mdb.enums.PlatformRetCodeEnum;
import com.mdb.open.common.enums.TradeWebErrorCodeEnum;
import com.mdb.open.common.enums.trade.status.CustomsUploadStatusEnum;
import com.mdb.open.common.enums.trade.status.ItemUploadStatusEnum;
import com.mdb.open.common.enums.trade.status.TradeFileApplyStatusEnum;
import com.mdb.open.common.enums.trade.status.TradeFileStatusEnum;
import com.mdb.open.trade.config.TradeOpenProperties;
import com.mdb.open.trade.domain.bo.trade.*;
import com.mdb.open.trade.domain.po.trade.*;
import com.mdb.open.trade.feign.RiskClient;
import com.mdb.open.trade.feign.dto.StartRiskModelDto;
import com.mdb.open.trade.service.trade.*;
import com.mdb.open.trade.utils.NumUtils;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Map;

/**
 * @description:
 * @author: you.yichao
 * @create: 2019-08-09 15:22
 **/
@Log4j2
@Service
public class TradeFileFacade {

    @Autowired
    TfAttachFileService tfAttachFileService;

    @Autowired
    TfTradeFileBasicInfoService tfTradeFileBasicInfoService;

    @Autowired
    TfTradeFileCustomsInfoService tfTradeFileCustomsInfoService;

    @Autowired
    TfTradeFileExtendInfoService tfTradeFileExtendInfoService;

    @Autowired
    TfTradeFileItemInfoService tfTradeFileItemInfoService;

    @Autowired
    TfTradeFileTransportInfoService tfTradeFileTransportInfoService;

    @Autowired
    RiskClient riskClient;

    @Autowired
    TradeOpenProperties tradeOpenProperties;

    @DS(MdbDataSource.MASTER)
    @Transactional
    public ResultEx<TradeFileBasicInfo> tempSaveTradeFile(TradeFileTempSaveBo bo) {

        String tradeFileNo = bo.getTradeFileTempBasicInfoBo().getTradeFileNo();
        TradeFileBasicInfo basicInfo = null;

        if (ObjectUtil.isNotEmpty(tradeFileNo)) {
            ResultEx<TradeFileBasicInfo> basicInfoEx = tfTradeFileBasicInfoService.getInfoByNo(tradeFileNo);
            if (basicInfoEx.isFailed() || ObjectUtil.isEmpty(basicInfoEx.getData())) {
                return ResultEx.fail();
            }
            basicInfo = basicInfoEx.getData();
            if (TradeFileStatusEnum.COMPLETED.equals(basicInfo.getStatus()) || !TradeFileApplyStatusEnum.INIT.equals(basicInfo.getApplyStatus())) {
                return ResultEx.makeResult(PlatformRetCodeEnum.TRADE_FILE_STATUS_WRONG);
            }
            //todo 测一下 传空会不会存空的进去
            tfTradeFileBasicInfoService.updateBasicInfo(bo.getTradeFileTempBasicInfoBo());
            TradeFileBasicInfo updateInfo = new TradeFileBasicInfo();
            updateInfo.setTradeFileNo(basicInfo.getTradeFileNo());
            updateInfo.setCustomerCode(basicInfo.getCustomerCode());
            updateInfo.setCustomerName(basicInfo.getCustomerName());
            updateInfo.setMcustomerCode(basicInfo.getMcustomerCode());
            updateInfo.setMerchantNo(basicInfo.getMerchantNo());
            updateInfo.setMerchantName(basicInfo.getMerchantName());
            updateInfo.setBusinessNo(bo.getTradeFileTempBasicInfoBo().getBusinessNo());
            updateInfo.setBusinessType(bo.getTradeFileTempBasicInfoBo().getBusinessType());
            updateInfo.setImporterCnName(bo.getTradeFileTempBasicInfoBo().getImporterCnName());
            updateInfo.setImporterEnName(bo.getTradeFileTempBasicInfoBo().getImporterEnName());
            updateInfo.setImporterAddress(bo.getTradeFileTempBasicInfoBo().getImporterAddress());
            updateInfo.setCustomsAmount(bo.getTradeFileTempBasicInfoBo().getCustomsAmount());
            updateInfo.setCustomsCnt(bo.getTradeFileTempBasicInfoBo().getCustomsCnt());
            updateInfo.setCustomsTime(bo.getTradeFileTempBasicInfoBo().getCustomsTime());
            updateInfo.setContractAmount(bo.getTradeFileTempBasicInfoBo().getContractAmount());
            updateInfo.setContractCcy(bo.getTradeFileTempBasicInfoBo().getContractCcy());
            updateInfo.setItemsAmount(bo.getTradeFileTempBasicInfoBo().getItemsAmount());
            updateInfo.setStatus(bo.getTradeFileTempBasicInfoBo().getStatus());
            updateInfo.setApplyStatus(bo.getTradeFileTempBasicInfoBo().getApplyStatus());
            updateInfo.setExportVeriStatus(bo.getTradeFileTempBasicInfoBo().getExportVeriStatus());
            updateInfo.setSourceType(bo.getTradeFileTempBasicInfoBo().getSourceType());

            basicInfo = updateInfo;

        } else {
            ResultEx<TradeFileBasicInfo> saveInfoEx = tfTradeFileBasicInfoService.saveBasicInfo(bo.getTradeFileTempBasicInfoBo());
            if (saveInfoEx.isFailed()) {
                return ResultEx.fail();
            }
            basicInfo = saveInfoEx.getData();
        }

        BigDecimal depositAmount = BigDecimal.ZERO;
        //额外信息
        if (ObjectUtil.isNotEmpty(bo.getTradeFileTempExtendInfoBo())) {

            ResultEx<TradeFileExtendInfo> extendInfoEx = tfTradeFileExtendInfoService.getInfoByNo(tradeFileNo);
            if (extendInfoEx.isFailed()) {
                return ResultEx.makeResult(extendInfoEx.getRetCode(), extendInfoEx.getRetMsg());
            }

            if (ObjectUtil.isEmpty(extendInfoEx.getData())) {
                SaveTradeFileExtendInfoBo saveExtendInfoBo = new SaveTradeFileExtendInfoBo();
                saveExtendInfoBo.setTradeFileNo(basicInfo.getTradeFileNo());
                saveExtendInfoBo.setBusinessNo(basicInfo.getBusinessNo());
                saveExtendInfoBo.setCustomerCode(basicInfo.getCustomerCode());
                saveExtendInfoBo.setMcustomerCode(basicInfo.getMcustomerCode());
                saveExtendInfoBo.setCustomerName(basicInfo.getCustomerName());
                saveExtendInfoBo.setMerchantNo(basicInfo.getMerchantNo());
                saveExtendInfoBo.setMerchantName(basicInfo.getMerchantName());
                saveExtendInfoBo.setSourceType(basicInfo.getSourceType());

                saveExtendInfoBo.setDepositAmount(bo.getTradeFileTempExtendInfoBo().getDepositAmount());
                saveExtendInfoBo.setDepositCcy(bo.getTradeFileTempExtendInfoBo().getDepositCcy());
                saveExtendInfoBo.setDepositPercent(bo.getTradeFileTempExtendInfoBo().getDepositPercent());
                saveExtendInfoBo.setInsuranceAmount(bo.getTradeFileTempExtendInfoBo().getInsuranceAmount());
                saveExtendInfoBo.setInsuranceCcy(bo.getTradeFileTempExtendInfoBo().getInsuranceCcy());
                saveExtendInfoBo.setInsurancePercent(bo.getTradeFileTempExtendInfoBo().getInsurancePercent());
                depositAmount = bo.getTradeFileTempExtendInfoBo().getDepositAmount();

                ResultEx saveExtendEx = tfTradeFileExtendInfoService.saveExtendInfo(saveExtendInfoBo);
                if (saveExtendEx.isFailed()) {
                    return saveExtendEx;
                }
            } else {

                UpdateTradeFileExtendInfoBo updateExtendInfoBo = new UpdateTradeFileExtendInfoBo();
                updateExtendInfoBo.setTradeFileNo(basicInfo.getTradeFileNo());
                updateExtendInfoBo.setDepositAmount(bo.getTradeFileTempExtendInfoBo().getDepositAmount());
                updateExtendInfoBo.setDepositCcy(bo.getTradeFileTempExtendInfoBo().getDepositCcy());
                updateExtendInfoBo.setDepositPercent(bo.getTradeFileTempExtendInfoBo().getDepositPercent());
                updateExtendInfoBo.setInsuranceAmount(bo.getTradeFileTempExtendInfoBo().getInsuranceAmount());
                updateExtendInfoBo.setInsuranceCcy(bo.getTradeFileTempExtendInfoBo().getInsuranceCcy());
                updateExtendInfoBo.setInsurancePercent(bo.getTradeFileTempExtendInfoBo().getInsurancePercent());

                depositAmount = bo.getTradeFileTempExtendInfoBo().getDepositAmount();
                ResultEx updateExtendEx = tfTradeFileExtendInfoService.updateExtendInfo(updateExtendInfoBo);
                if (updateExtendEx.isFailed()) {
                    return updateExtendEx;
                }
            }
            if (NumUtils.toBigDecimal(depositAmount).compareTo(BigDecimal.ZERO) != 0 &&
                    NumUtils.toBigDecimal(depositAmount).compareTo(NumUtils.toBigDecimal(basicInfo.getContractAmount())) >= 0) {
                return ResultEx.fail(TradeWebErrorCodeEnum.DEPOSIT_AMOUNT_OVER_CONTRACT_AMOUNT.getText());
            }
        }

        //海关信息
        if (ObjectUtil.isNotEmpty(bo.getTradeFileTempCustomsListBoList())) {
            if (tradeOpenProperties.getCustomsSize() < bo.getTradeFileTempCustomsListBoList().size()) {
                return ResultEx.fail(TradeWebErrorCodeEnum.CUSTOMS_SIZE_LESS_THAN_5.getText());
            }
            BigDecimal customsAmount = BigDecimal.ZERO;
            for (TradeFileTempCustomsListBo customsListBo : bo.getTradeFileTempCustomsListBoList()) {
                //海关信息
                String tradeFileCustomsNo = null;
                String customsNo = null;
                customsAmount = customsAmount.add(NumUtils.toBigDecimal(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsAmount()));
                if (ObjectUtil.isEmpty(customsListBo.getTradeFileTempCustomsInfoBo().getTradeFileCustomsNo())) {
                    ResultEx<Map<String, String>> mapEx = this.saveCustoms(basicInfo, customsListBo);
                    if (mapEx.isFailed()) {
                        return ResultEx.makeResult(mapEx.getRetCode(), mapEx.getRetMsg());
                    }
                    tradeFileCustomsNo = mapEx.getData().get("tradeFileCustomsNo");
                    customsNo = mapEx.getData().get("customsNo");
                } else {
                    ResultEx<Map<String, String>> mapEx = this.updateCustoms(basicInfo, customsListBo);
                    if (mapEx.isFailed()) {
                        return ResultEx.makeResult(mapEx.getRetCode(), mapEx.getRetMsg());
                    }
                    tradeFileCustomsNo = mapEx.getData().get("tradeFileCustomsNo");
                    customsNo = mapEx.getData().get("customsNo");

                }

                //运输信息
                if (ObjectUtil.isNotEmpty(customsListBo.getTradeFileTempTransportInfoBo())) {

                    ResultEx<TradeFileTransportInfo> fileTransportInfoEx = tfTradeFileTransportInfoService.getInfoByNo(tradeFileNo,
                            tradeFileCustomsNo == null ? customsListBo.getTradeFileTempTransportInfoBo().getTradeFileCustomsNo() : tradeFileCustomsNo);
                    if (fileTransportInfoEx.isFailed()) {
                        return ResultEx.makeResult(fileTransportInfoEx.getRetCode(), fileTransportInfoEx.getRetMsg());
                    }

                    if (ObjectUtil.isEmpty(fileTransportInfoEx.getData())) {

                        ResultEx ex = this.saveTransport(basicInfo, customsListBo, customsNo, tradeFileCustomsNo);
                        if (ex.isFailed()) {
                            return ex;
                        }

                    } else {

                        ResultEx ex = this.updateTransport(basicInfo, customsListBo, customsNo, tradeFileCustomsNo);
                        if (ex.isFailed()) {
                            return ex;
                        }
                    }
                } else if (ObjectUtil.isNotEmpty(customsNo)) {

                    ResultEx<TradeFileTransportInfo> fileTransportInfoEx = tfTradeFileTransportInfoService.getInfoByNo(tradeFileNo,
                            tradeFileCustomsNo == null ? customsListBo.getTradeFileTempTransportInfoBo().getTradeFileCustomsNo() : tradeFileCustomsNo);
                    if (fileTransportInfoEx.isFailed()) {
                        return ResultEx.makeResult(fileTransportInfoEx.getRetCode(), fileTransportInfoEx.getRetMsg());
                    }
                    if (ObjectUtil.isNotEmpty(fileTransportInfoEx.getData())) {
                        ResultEx ex = this.updateTransport(basicInfo, customsListBo, customsNo, tradeFileCustomsNo);
                        if (ex.isFailed()) {
                            return ex;
                        }
                    }
                }

                //商品信息
                if (ObjectUtil.isNotEmpty(customsListBo.getTradeFileTempItemInfoBoList())) {

                    for (TradeFileTempItemInfoBo itemInfoBo : customsListBo.getTradeFileTempItemInfoBoList()) {
                        if (ObjectUtil.isEmpty(itemInfoBo.getTradeFileItemNo())) {

                            ResultEx ex = this.saveItem(basicInfo, itemInfoBo, customsNo, tradeFileCustomsNo);
                            if (ex.isFailed()) {
                                return ex;
                            }

                        } else {
                            ResultEx ex = this.updateItem(basicInfo, itemInfoBo, customsNo, tradeFileCustomsNo);
                            if (ex.isFailed()) {
                                return ex;
                            }
                        }
                    }
                } else if (ObjectUtil.isNotEmpty(customsNo)) {

                    ResultEx ex = this.updateItem(basicInfo, new TradeFileTempItemInfoBo(), customsNo, tradeFileCustomsNo);
                    if (ex.isFailed()) {
                        return ex;
                    }
                }
            }
            if (NumUtils.toBigDecimal(depositAmount).compareTo(BigDecimal.ZERO) != 0 && NumUtils.toBigDecimal(depositAmount).compareTo(customsAmount) >= 0) {
                return ResultEx.fail(TradeWebErrorCodeEnum.DEPOSIT_AMOUNT_OVER_CONTRACT_AMOUNT.getText());
            }
        }


        if (ObjectUtil.isNotEmpty(bo.getInsertList())) {
            for (AttachFile file : bo.getInsertList()) {
                file.setApplyOrderNo(basicInfo.getTradeFileNo());
            }
            tfAttachFileService.saveBatch(bo.getInsertList());
        }
        if (ObjectUtil.isNotEmpty(bo.getRemoveList())) {
            tfAttachFileService.batchRemoveAttachFile(bo.getRemoveList());
        }

        return ResultEx.ok(basicInfo);
    }

    private ResultEx<Map<String, String>> saveCustoms(TradeFileBasicInfo basicInfo, TradeFileTempCustomsListBo customsListBo) {

        int cnt = tfTradeFileCustomsInfoService.count(new LambdaQueryWrapper<TradeFileCustomsInfo>()
                .eq(TradeFileCustomsInfo::getCustomsNo, customsListBo.getTradeFileTempCustomsInfoBo().getCustomsNo())
                .eq(TradeFileCustomsInfo::getTradeFileNo, basicInfo.getTradeFileNo()));
        if (cnt > 0) {
            return ResultEx.fail(TradeWebErrorCodeEnum.CUSTOMS_NO_DUPLICATE.getText());
        }

        SaveTradeFileCustomsInfoBo saveCustomsInfoBo = new SaveTradeFileCustomsInfoBo();
        saveCustomsInfoBo.setTradeFileNo(basicInfo.getTradeFileNo());
        saveCustomsInfoBo.setBusinessNo(basicInfo.getBusinessNo());
        saveCustomsInfoBo.setCustomerCode(basicInfo.getCustomerCode());
        saveCustomsInfoBo.setMcustomerCode(basicInfo.getMcustomerCode());
        saveCustomsInfoBo.setCustomerName(basicInfo.getCustomerName());
        saveCustomsInfoBo.setMerchantNo(basicInfo.getMerchantNo());
        saveCustomsInfoBo.setMerchantName(basicInfo.getMerchantName());
        saveCustomsInfoBo.setSourceType(basicInfo.getSourceType());

        saveCustomsInfoBo.setCustomsNo(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsNo());
        saveCustomsInfoBo.setCustomsLocation(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsLocation());
        saveCustomsInfoBo.setCustomsTitle(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsTitle());
        saveCustomsInfoBo.setCustomsAmount(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsAmount());
        saveCustomsInfoBo.setCcy(customsListBo.getTradeFileTempCustomsInfoBo().getCcy());
        saveCustomsInfoBo.setCommitTime(customsListBo.getTradeFileTempCustomsInfoBo().getCommitTime());
        saveCustomsInfoBo.setLoadingPort(customsListBo.getTradeFileTempCustomsInfoBo().getLoadingPort());
        saveCustomsInfoBo.setLoadingPortCode(customsListBo.getTradeFileTempCustomsInfoBo().getLoadingPortCode());
        saveCustomsInfoBo.setDestinPort(customsListBo.getTradeFileTempCustomsInfoBo().getDestinPort());
        saveCustomsInfoBo.setDestinPortCode(customsListBo.getTradeFileTempCustomsInfoBo().getDestinPortCode());
        saveCustomsInfoBo.setDestinCountry(customsListBo.getTradeFileTempCustomsInfoBo().getDestinCountry());
        ResultEx<TradeFileCustomsInfo> saveCustomsEx = tfTradeFileCustomsInfoService.saveCustomsInfo(saveCustomsInfoBo);
        if (saveCustomsEx.isFailed()) {
            return ResultEx.makeResult(saveCustomsEx.getRetCode(), saveCustomsEx.getRetMsg());
        }

        Map<String, String> map = Maps.newHashMap();

        map.put("tradeFileCustomsNo", saveCustomsEx.getData().getTradeFileCustomsNo());
        map.put("customsNo", customsListBo.getTradeFileTempCustomsInfoBo().getCustomsNo());

        return ResultEx.ok(map);
    }

    private ResultEx<Map<String, String>> updateCustoms(TradeFileBasicInfo basicInfo, TradeFileTempCustomsListBo customsListBo) {
        UpdateTradeFileCustomsInfoBo updateCustomsInfoBo = new UpdateTradeFileCustomsInfoBo();
        updateCustomsInfoBo.setTradeFileNo(basicInfo.getTradeFileNo());
        updateCustomsInfoBo.setTradeFileCustomsNo(customsListBo.getTradeFileTempCustomsInfoBo().getTradeFileCustomsNo());
        Map<String, String> map = Maps.newHashMap();

        map.put("tradeFileCustomsNo", customsListBo.getTradeFileTempCustomsInfoBo().getTradeFileCustomsNo());
        if (CustomsUploadStatusEnum.UPDATE.equals(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsUploadStatusEnum())) {

            TradeFileCustomsInfo customsInfo = tfTradeFileCustomsInfoService.getLimitOne(new LambdaQueryWrapper<TradeFileCustomsInfo>()
                    .eq(TradeFileCustomsInfo::getCustomsNo, customsListBo.getTradeFileTempCustomsInfoBo().getCustomsNo())
                    .eq(TradeFileCustomsInfo::getTradeFileNo, basicInfo.getTradeFileNo()));
            if (ObjectUtil.isNotEmpty(customsInfo)) {
                if (!customsInfo.getTradeFileCustomsNo().equals(customsListBo.getTradeFileTempCustomsInfoBo().getTradeFileCustomsNo())) {
                    return ResultEx.fail(TradeWebErrorCodeEnum.CUSTOMS_NO_DUPLICATE.getText());
                }
            }

            map.put("customsNo", customsListBo.getTradeFileTempCustomsInfoBo().getCustomsNo());
            updateCustomsInfoBo.setCustomsNo(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsNo());
            updateCustomsInfoBo.setCustomsLocation(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsLocation());
            updateCustomsInfoBo.setCustomsTitle(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsTitle());
            updateCustomsInfoBo.setCustomsAmount(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsAmount());
            updateCustomsInfoBo.setCcy(customsListBo.getTradeFileTempCustomsInfoBo().getCcy());
            updateCustomsInfoBo.setCommitTime(customsListBo.getTradeFileTempCustomsInfoBo().getCommitTime());
            updateCustomsInfoBo.setLoadingPort(customsListBo.getTradeFileTempCustomsInfoBo().getLoadingPort());
            updateCustomsInfoBo.setLoadingPortCode(customsListBo.getTradeFileTempCustomsInfoBo().getLoadingPortCode());
            updateCustomsInfoBo.setDestinPort(customsListBo.getTradeFileTempCustomsInfoBo().getDestinPort());
            updateCustomsInfoBo.setDestinPortCode(customsListBo.getTradeFileTempCustomsInfoBo().getDestinPortCode());
            updateCustomsInfoBo.setDestinCountry(customsListBo.getTradeFileTempCustomsInfoBo().getDestinCountry());
            ResultEx updateCustomsEx = tfTradeFileCustomsInfoService.updateCustomsInfo(updateCustomsInfoBo);
            if (updateCustomsEx.isFailed()) {
                return updateCustomsEx;
            }
        } else if (CustomsUploadStatusEnum.DELETE.equals(customsListBo.getTradeFileTempCustomsInfoBo().getCustomsUploadStatusEnum())) {
            ResultEx removeItemEx = tfTradeFileCustomsInfoService.removeCustomsInfo(updateCustomsInfoBo);
            if (removeItemEx.isFailed()) {
                return removeItemEx;
            }
        }

        return ResultEx.ok(map);
    }

    private ResultEx saveTransport(TradeFileBasicInfo basicInfo, TradeFileTempCustomsListBo customsListBo, String customsNo, String tradeFileCustomsNo) {

        SaveTradeFileTransportInfoBo transportInfoBo = new SaveTradeFileTransportInfoBo();
        transportInfoBo.setTradeFileNo(basicInfo.getTradeFileNo());
        transportInfoBo.setBusinessNo(basicInfo.getBusinessNo());
        transportInfoBo.setCustomerCode(basicInfo.getCustomerCode());
        transportInfoBo.setMcustomerCode(basicInfo.getMcustomerCode());
        transportInfoBo.setCustomerName(basicInfo.getCustomerName());
        transportInfoBo.setMerchantNo(basicInfo.getMerchantNo());
        transportInfoBo.setMerchantName(basicInfo.getMerchantName());
        transportInfoBo.setSourceType(basicInfo.getSourceType());
        transportInfoBo.setCustomsNo(customsNo == null ? customsListBo.getTradeFileTempTransportInfoBo().getCustomsNo() : customsNo);
        transportInfoBo.setTradeFileCustomsNo(tradeFileCustomsNo == null ? customsListBo.getTradeFileTempTransportInfoBo().getTradeFileCustomsNo() : tradeFileCustomsNo);

        transportInfoBo.setLadingBillNo(customsListBo.getTradeFileTempTransportInfoBo().getLadingBillNo());
        transportInfoBo.setContainerNo(customsListBo.getTradeFileTempTransportInfoBo().getContainerNo());
        transportInfoBo.setShipper(customsListBo.getTradeFileTempTransportInfoBo().getShipper());
        transportInfoBo.setReceiverCnName(customsListBo.getTradeFileTempTransportInfoBo().getReceiverCnName());
        transportInfoBo.setReceiverEnName(customsListBo.getTradeFileTempTransportInfoBo().getReceiverEnName());
        transportInfoBo.setShipLoadTime(customsListBo.getTradeFileTempTransportInfoBo().getShipLoadTime());
        transportInfoBo.setReceiverCountry(customsListBo.getTradeFileTempTransportInfoBo().getReceiverCountry());
        transportInfoBo.setTransportName(customsListBo.getTradeFileTempTransportInfoBo().getTransportName());
        transportInfoBo.setTransportType(customsListBo.getTradeFileTempTransportInfoBo().getTransportType());

        ResultEx saveTransportEx = tfTradeFileTransportInfoService.saveTransportInfo(transportInfoBo);
        if (saveTransportEx.isFailed()) {
            return saveTransportEx;
        }

        return ResultEx.ok();
    }

    private ResultEx updateTransport(TradeFileBasicInfo basicInfo, TradeFileTempCustomsListBo customsListBo, String customsNo, String tradeFileCustomsNo) {

        UpdateTradeFileTransportInfoBo updateTransportInfo = new UpdateTradeFileTransportInfoBo();
        updateTransportInfo.setTradeFileNo(basicInfo.getTradeFileNo());
        updateTransportInfo.setTradeFileCustomsNo(tradeFileCustomsNo == null ? customsListBo.getTradeFileTempTransportInfoBo().getTradeFileCustomsNo() : tradeFileCustomsNo);
        if (ObjectUtil.isNotEmpty(customsNo)) {
            updateTransportInfo.setCustomsNo(customsNo);
        }

        if (ObjectUtil.isNotEmpty(customsListBo.getTradeFileTempTransportInfoBo())) {

            updateTransportInfo.setCustomsNo(customsListBo.getTradeFileTempTransportInfoBo().getCustomsNo());
            updateTransportInfo.setLadingBillNo(customsListBo.getTradeFileTempTransportInfoBo().getLadingBillNo());
            updateTransportInfo.setContainerNo(customsListBo.getTradeFileTempTransportInfoBo().getContainerNo());
            updateTransportInfo.setShipper(customsListBo.getTradeFileTempTransportInfoBo().getShipper());
            updateTransportInfo.setReceiverCnName(customsListBo.getTradeFileTempTransportInfoBo().getReceiverCnName());
            updateTransportInfo.setReceiverEnName(customsListBo.getTradeFileTempTransportInfoBo().getReceiverEnName());
            updateTransportInfo.setShipLoadTime(customsListBo.getTradeFileTempTransportInfoBo().getShipLoadTime());
            updateTransportInfo.setReceiverCountry(customsListBo.getTradeFileTempTransportInfoBo().getReceiverCountry());
            updateTransportInfo.setTransportName(customsListBo.getTradeFileTempTransportInfoBo().getTransportName());
            updateTransportInfo.setTransportType(customsListBo.getTradeFileTempTransportInfoBo().getTransportType());
        }

        ResultEx updateTransportEx = tfTradeFileTransportInfoService.updateTransportInfo(updateTransportInfo);
        if (updateTransportEx.isFailed()) {
            return updateTransportEx;
        }

        return ResultEx.ok();
    }

    private ResultEx saveItem(TradeFileBasicInfo basicInfo, TradeFileTempItemInfoBo itemInfoBo, String customsNo, String tradeFileCustomsNo) {

        SaveTradeFileItemInfoBo saveItemInfoBo = new SaveTradeFileItemInfoBo();
        saveItemInfoBo.setTradeFileNo(basicInfo.getTradeFileNo());
        saveItemInfoBo.setCustomerCode(basicInfo.getCustomerCode());
        saveItemInfoBo.setMcustomerCode(basicInfo.getMcustomerCode());
        saveItemInfoBo.setCustomerName(basicInfo.getCustomerName());
        saveItemInfoBo.setMerchantNo(basicInfo.getMerchantNo());
        saveItemInfoBo.setMerchantName(basicInfo.getMerchantName());
        saveItemInfoBo.setBusinessNo(basicInfo.getBusinessNo());
        saveItemInfoBo.setCustomsNo(customsNo == null ? itemInfoBo.getCustomsNo() : customsNo);
        saveItemInfoBo.setTradeFileCustomsNo(tradeFileCustomsNo == null ? itemInfoBo.getTradeFileCustomsNo() : tradeFileCustomsNo);

        saveItemInfoBo.setItemCnName(itemInfoBo.getItemCnName());
        saveItemInfoBo.setItemEnName(itemInfoBo.getItemEnName());
        saveItemInfoBo.setHsCode(itemInfoBo.getHsCode());
        saveItemInfoBo.setBrand(itemInfoBo.getBrand());
        saveItemInfoBo.setUnit(itemInfoBo.getUnit());
        saveItemInfoBo.setQuantity(itemInfoBo.getQuantity());
        saveItemInfoBo.setCustomUnitAmount(itemInfoBo.getCustomUnitAmount());
        saveItemInfoBo.setCustomUnitCcy(itemInfoBo.getCustomUnitCcy());
        saveItemInfoBo.setCustomTotalAmount(itemInfoBo.getCustomTotalAmount());
        saveItemInfoBo.setCustomTotalCcy(itemInfoBo.getCustomTotalCcy());
        saveItemInfoBo.setSourceType(basicInfo.getSourceType());

        ResultEx saveItemEx = tfTradeFileItemInfoService.saveItemInfo(saveItemInfoBo);
        if (saveItemEx.isFailed()) {
            return saveItemEx;
        }

        return ResultEx.ok();
    }

    private ResultEx updateItem(TradeFileBasicInfo basicInfo, TradeFileTempItemInfoBo itemInfoBo, String customsNo, String tradeFileCustomsNo) {

        UpdateTradeFileItemInfoBo updateItemInfo = new UpdateTradeFileItemInfoBo();
        updateItemInfo.setTradeFileNo(basicInfo.getTradeFileNo());
        updateItemInfo.setTradeFileCustomsNo(tradeFileCustomsNo == null ? itemInfoBo.getTradeFileCustomsNo() : tradeFileCustomsNo);
        if (ObjectUtil.isNotEmpty(customsNo)) {
            updateItemInfo.setCustomsNo(customsNo);
        }

        if (ItemUploadStatusEnum.UPDATE.equals(itemInfoBo.getItemUploadStatusEnum())) {
            updateItemInfo.setTradeFileItemNo(itemInfoBo.getTradeFileItemNo());
            updateItemInfo.setCustomsNo(itemInfoBo.getCustomsNo());
            updateItemInfo.setItemCnName(itemInfoBo.getItemCnName());
            updateItemInfo.setItemEnName(itemInfoBo.getItemEnName());
            updateItemInfo.setHsCode(itemInfoBo.getHsCode());
            updateItemInfo.setBrand(itemInfoBo.getBrand());
            updateItemInfo.setUnit(itemInfoBo.getUnit());
            updateItemInfo.setQuantity(itemInfoBo.getQuantity());
            updateItemInfo.setCustomUnitAmount(itemInfoBo.getCustomUnitAmount());
            updateItemInfo.setCustomUnitCcy(itemInfoBo.getCustomUnitCcy());
            updateItemInfo.setCustomTotalAmount(itemInfoBo.getCustomTotalAmount());
            updateItemInfo.setCustomTotalCcy(itemInfoBo.getCustomTotalCcy());
            ResultEx updateItemEx = tfTradeFileItemInfoService.updateItemInfo(updateItemInfo);
            if (updateItemEx.isFailed()) {
                return updateItemEx;
            }
        } else if (ItemUploadStatusEnum.DELETE.equals(itemInfoBo.getItemUploadStatusEnum())) {
            ResultEx removeItemEx = tfTradeFileItemInfoService.removeItemInfo(updateItemInfo);
            if (removeItemEx.isFailed()) {
                return removeItemEx;
            }
        }
        return ResultEx.ok();
    }

    @Async
    @Retryable(value = Exception.class, maxAttempts = 20, backoff = @Backoff(delay = 2000, multiplier = 2))
    public void startRisk(StartRiskModelDto riskModelDto) {
        ResultEx riskEx = riskClient.start(riskModelDto);
        riskEx.assertSuccess();
    }

    @Recover
    public void startRiskRecover(Exception e, StartRiskModelDto riskModelDto) {
        log.error("调用风控模型失败, param:{}", JSON.toJSONString(riskModelDto), e);
    }
}
